#version 450 core

layout (location = 0) out vec4 o_Color;
//out int o_EntityID;

struct VertexOutput
{
	vec4 Color;
	vec2 TexCoord;
	float TilingFactor;
	vec2 UV;
};

layout (location = 0) in VertexOutput Output;
layout (location = 4) in float v_TexIndex;
layout (location = 5) in flat int v_EntityID;

uniform mediump vec2 TextureSize0;
uniform lowp float Time; 

uniform sampler2D u_Textures[5];
uniform sampler2D TextTexture;
uniform vec4 TextColor;
uniform vec4 Lines[8];

#define PI 3.14

float circleshape(vec2 position, float radius)
{
    //return step(radius, length(position));
    return step(length(position), radius);
}

float DE( vec2 pp, out bool blood, float t )
{
	pp.y += (
		.4 * sin(.5*2.3*pp.x+pp.y) +
		.2 * sin(.5*5.5*pp.x+pp.y) +
		0.1*sin(.5*13.7*pp.x)+
		0.06*sin(.5*23.*pp.x));
	
	pp += vec2(0.,0.4)*t;
	
	float thresh = 5.3;
	
	blood = pp.y > thresh;
	
	float d = abs(pp.y - thresh);
	// todo use proper implicit dist
	//d /= sqrt(1.+grad*grad);
	return d;
}

vec3 sceneColour( in vec2 pp )
{
	float endTime = 16.;
	float rewind = 2.;
	float t = mod( Time, endTime+rewind );
	
	//if( t > endTime )
	//	t = endTime * (1.-(t-endTime)/rewind);
	
	bool blood;
	float d = DE( pp, blood, t );
	
	if( !blood )
	{
		// floor. not really happy with this at the moment..
		vec3 floorCol = vec3(.25);
		
		//floorCol = texture( iChannel0, -(vec2(pp.x/20.,pp.y/33.)+vec2(.5,.02)) ).xyz;
		float floori = (floorCol.x+floorCol.y+floorCol.z)/3.;
		
		floori = smoothstep(0.5,.53,floori) ;
		floori = smoothstep(-5.15,1.,floori);
		floori = 1.-floori;
		floorCol = vec3(floori);
		
		// ao from blood
		float ao = clamp( smoothstep(0.,.2,d), 0., 1.);
		return mix(1.,sqrt(ao),.25) * vec3(0.0,0.0,0.0);
		//return mix(1.,sqrt(ao),.25) * floorCol;
	}
	else
	{
		//blood. fake a 3d look
		//height
		float h = clamp( smoothstep(.0,.25,d), 0., 1.);
		h = 4.*pow(h,.2);
		// couldnt get matching results using finite diffs, need to sort this out.
		/*vec2 eps = vec2(0.,.01);
		float dx = clamp( smoothstep(.0,.25,DE(pp+eps.yx,blood,t)), 0., 1.);
		dx = (dx - h)/eps.y;
		float dy = clamp( smoothstep(.0,.25,DE(pp+eps.xy,blood,t)), 0., 1.);
		dy = (dy - h)/eps.y;*/
		//vec3 N = vec3(-dx, 1., -dy );
		
		// gradient instructions. easy but produces artifacts
		vec3 N = vec3(-dFdx(h), 1., -dFdy(h) );
		N = normalize(N);
		vec3 L = normalize(vec3(.5,.7,-.5));
		vec3 res = pow(dot(N,L),10.)*vec3(1.);
		// make it more red hack
		res += vec3(.5,-.3,-0.3);
		// window refl
		vec2 off = pp-vec2(5.3,2.);
		
		float r = length(off);
		float v = 1.;
		float band = 20./TextureSize0.x;
		v *= smoothstep( 0.8, .8+band, r );
		v *= smoothstep( 2.1, 2.1-band, r );
		float gap1 = smoothstep(1.3,1.3-band,r) + smoothstep( 1.4,1.4+band,r);
		v*= gap1;
		
		// the witness
		float h1t = 3.;
		float h2t = 4.1;
		float ht = 5.;
		float hand1p = 1.-clamp((t-h1t)/5.,0.,1.);
		float hand2p = 1.-clamp((t-h2t)/5.,0.,1.);
		float headp = smoothstep(0.,1.,1.-clamp((t-ht)/6.,0.,1.));
		v *= smoothstep(.06,.06+band, length(pp-vec2(6.71,3.61)-vec2(hand1p)));
		v *= smoothstep(.06,.06+band, length(pp-vec2(7.04,3.25)-vec2(hand2p)));
		v *= smoothstep(.13,.13+band, length(pp-vec2(6.84,3.4)-vec2(headp)));
		// ears
		v *= smoothstep(.02,.02+band, length(pp-vec2(6.74,3.49)-vec2(headp)));
		v *= smoothstep(.02,.02+band, length(pp-vec2(6.93,3.3)-vec2(headp)));
		
		band /= r;
		float a = atan( off.y, off.x );
		v *= smoothstep( 0.5,0.5+band, a);
		v *= smoothstep( 1.8,1.8-band, a);
		float gap2 = smoothstep( 1.1,1.1-band, a) + smoothstep( 1.2,1.2+band, a);
		v *= gap2;
		
		v *= .95;
		res = (1.-v)*res + v*vec3(1.);
		
		return res;
	}
}


void main()
{
	vec4 texColor = Output.Color;
    vec2 uv = Output.TexCoord * Output.TilingFactor;
    vec2 UV = uv;

	switch(int(v_TexIndex))
	{
		case  0: texColor *= texture(u_Textures[0], uv); break;
	}

    vec4 textColor = texture(TextTexture, uv);

    float ratio = TextureSize0.x / TextureSize0.y;

    float radius = 0.01;

    for(int a=0; a<8; ++a){
        //vec4 line1 = Lines[a];
        vec4 line1 = vec4(Lines[a][0] / TextureSize0.x, Lines[a][1] / TextureSize0.y, Lines[a][2] / TextureSize0.x, Lines[a][3] / TextureSize0.y);

        float line1XEnable = step(line1[0]-radius*0.5, uv.x) * step(uv.x, line1[0]+radius*0.5);

        float range = line1[3] - line1[1];
        line1[3] = line1[1] + range * clamp(Time*0.1, 0.0, 1.0);

        float line1YEnable = step(uv.y, line1[3]) * step(line1[1], uv.y);
        
        vec2 translate = vec2(line1[0], line1[3]);

        vec2 coord = uv;
        coord -= translate;

        coord.x *= ratio;

        float circle = circleshape(coord, radius);
        textColor += vec4(1.0) * line1XEnable * line1YEnable;
        textColor += vec4(1.0) * (circle);
        
    }

    textColor = clamp(textColor, vec4(0.0), vec4(1.0));

    textColor *= TextColor;

    texColor = mix(texColor, textColor, textColor.a);

    vec3 bloodColor = sceneColour(vec2(UV.x*4.0, (1.0-UV.y)*4.0));

    texColor = mix(texColor, vec4(bloodColor, 1.0), step(0.001, bloodColor.r));

    //texColor = vec4(bloodColor, 1.0);

	if (texColor.a == 0.0)
		discard;

	o_Color = texColor;
	//o_Color = vec4(uv.x, uv.y, 0.0, 1.0);
}
